﻿using asprise_ocr_api;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Media.Imaging;

namespace Train.Code
{
    class PictureTool
    {
        //bitMap转换成Byte
        public byte[] BitmapToBytes(Bitmap bitmap)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Jpeg);
                byte[] data = new byte[stream.Length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, Convert.ToInt32(stream.Length));

                return data;
            }
        }

        //byte转换成BitmapImage
        public BitmapImage BytesToBitmapImage(byte[] theByte)
        {
            BitmapImage bitmap = new BitmapImage();
            using (MemoryStream stream = new MemoryStream(theByte, false))
            {
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = stream;
                bitmap.EndInit();
                bitmap.Freeze();

            }
            return bitmap;
        }

        //图片等比例缩放
        public Dictionary<string, int> AdjustSize(int spcWidth, int spcHeight, int orgWidth, int orgHeight)
        {
            Dictionary<string, int> size = new Dictionary<string, int>();
            // 原始宽高在指定宽高范围内，不作任何处理  
            if (orgWidth <= spcWidth && orgHeight <= spcHeight)
            {
                size["Width"] = orgWidth;
                size["Height"] = orgHeight;
            }
            else
            {
                // 取得比例系数  
                float w = orgWidth / (float)spcWidth;
                float h = orgHeight / (float)spcHeight;
                // 宽度比大于高度比  
                if (w > h)
                {
                    size["Width"] = spcWidth;
                    size["Height"] = (int)(w >= 1 ? Math.Round(orgHeight / w) : Math.Round(orgHeight * w));
                }
                // 宽度比小于高度比  
                else if (w < h)
                {
                    size["Height"] = spcHeight;
                    size["Width"] = (int)(h >= 1 ? Math.Round(orgWidth / h) : Math.Round(orgWidth * h));
                }
                // 宽度比等于高度比  
                else
                {
                    size["Width"] = spcWidth;
                    size["Height"] = spcHeight;
                }
            }
            return size;
        }

        #region 清除不需要的颜色(就是清除影响处理的颜色)
        /// <summary>
        /// 清除不必要颜色
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public Bitmap imgdo(Bitmap img)
        {
            //去色
            Bitmap btp = new Bitmap(img);
            System.Drawing.Color c = new System.Drawing.Color();
            int rr, gg, bb;
            for (int i = 0; i < btp.Width; i++)
            {
                for (int j = 0; j < btp.Height; j++)
                {
                    //取图片当前的像素点
                    c = btp.GetPixel(i, j);
                    rr = c.R; gg = c.G; bb = c.B;
                    //改变颜色
                    if (rr == 102 && gg == 0 && bb == 0)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                    if (rr == 153 && gg == 0 && bb == 0)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                    if (rr == 153 && gg == 0 && bb == 51)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                    if (rr == 153 && gg == 43 && bb == 51)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                    if (rr == 255 && gg == 255 && bb == 0)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                    if (rr == 255 && gg == 255 && bb == 51)
                    {
                        //重新设置当前的像素点
                        btp.SetPixel(i, j, System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    }
                }
            }
            return btp;
        }
        #endregion

        #region 将图片变成灰白
        /// <summary>
        /// 灰色
        /// </summary>
        /// <param name="btp">要处理的bit</param>
        /// <returns></returns>
        public Bitmap Gray(Bitmap btp)
        {
            //灰度
            Bitmap bmphd = new Bitmap(btp);
            for (int i = 0; i < bmphd.Width; i++)
            {
                for (int j = 0; j < bmphd.Height; j++)
                {
                    //取图片当前的像素点
                    var color = bmphd.GetPixel(i, j);

                    var gray = (int)(color.R * 0.001 + color.G * 0.700 + color.B * 0.250);

                    //重新设置当前的像素点
                    bmphd.SetPixel(i, j, System.Drawing.Color.FromArgb(gray, gray, gray));
                }
            }
            return bmphd;
        }
        #endregion

        #region 将图片二值化
        /// <summary>
        /// 二值化
        /// </summary>
        /// <param name="btp"></param>
        /// <returns></returns>
        public Bitmap binaryzation(Bitmap btp)
        {
            int w = btp.Width;
            int h = btp.Height;
            Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
            BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
            for (int y = 0; y < h; y++)
            {
                byte[] scan = new byte[(w + 7) / 8];
                for (int x = 0; x < w; x++)
                {
                    System.Drawing.Color c = btp.GetPixel(x, y);
                    if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
                }
                Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
            }
            bmp.UnlockBits(data);
            return bmp;
        }
        #endregion

        #region 将位图深度变为1
        /// <summary>
        /// 位图24转1
        /// </summary>
        /// <param name="SrcImg">需要处理的图片</param>
        /// <returns></returns>
        public Bitmap ConvertTo24bppTo1bpp(Bitmap SrcImg)
        {
            unsafe
            {
                byte* SrcPointer, DestPointer;
                int Width, Height, SrcStride, DestStride;
                int X, Y, Index, Sum; ;
                Bitmap DestImg = new Bitmap(SrcImg.Width, SrcImg.Height, System.Drawing.Imaging.PixelFormat.Format1bppIndexed);
                BitmapData SrcData = new BitmapData();
                SrcImg.LockBits(new System.Drawing.Rectangle(0, 0, SrcImg.Width, SrcImg.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, SrcData);
                BitmapData DestData = new BitmapData();
                DestImg.LockBits(new System.Drawing.Rectangle(0, 0, SrcImg.Width, SrcImg.Height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, DestData);
                Width = SrcImg.Width; Height = SrcImg.Height; SrcStride = SrcData.Stride; DestStride = DestData.Stride;
                for (Y = 0; Y < Height; Y++)
                {
                    SrcPointer = (byte*)SrcData.Scan0 + Y * SrcStride;
                    DestPointer = (byte*)DestData.Scan0 + Y * DestStride;
                    Index = 7; Sum = 0;
                    for (X = 0; X < Width; X++)
                    {
                        if (*SrcPointer + (*(SrcPointer + 1) << 1) + *(SrcPointer + 2) >= 512) Sum += (1 << Index);
                        if (Index == 0)
                        {
                            *DestPointer = (byte)Sum;
                            Sum = 0;
                            Index = 7;
                            DestPointer++;
                        }
                        else
                            Index--;
                        SrcPointer += 3;
                    }
                    if (Index != 7) *DestPointer = (byte)Sum;
                }
                SrcImg.UnlockBits(SrcData);
                DestImg.UnlockBits(DestData);
                return DestImg;
            }
        }
        #endregion
    }

    class GetStringInPictureTool
    {
        #region 读取图文

        /// <summary>
        /// 直接读取图文
        /// </summary>
        public string GetString(string path)
        {
            AspriseOCR.SetUp();
            AspriseOCR ocr = new AspriseOCR();
            ocr.StartEngine("eng", AspriseOCR.SPEED_FASTEST);
            string s = ocr.Recognize(path, -1, -1, -1, -1, -1, AspriseOCR.RECOGNIZE_TYPE_ALL, AspriseOCR.OUTPUT_FORMAT_PLAINTEXT);
            ocr.StopEngine();

            return s;
        }

        /// <summary>
        /// 读取图文去除没必要的讯息
        /// </summary>
        public string GetStringClearError(string path)
        {
            string s = GetString(path);
            if (s == string.Empty)
                return s;

            s = s.Replace("<error: currently only 1-bit black/white or 32bit RGB images are accepted for barcode recognition>", "");
            s = s.Replace("\n", "");

            return s;
        }

        #endregion
    }

    public static class MemoryTool
    {
        //清除bitmapSource
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr o);
    }
}
